# 导入基础
from rest_framework.pagination import BasePagination

from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
from users.models import User, Token, Roles, Permissions


class User(object):
    def __init__(self, name=None, role=None):
        self.name = name
        self.role = role

# 认证登陆组件
class MineBaseAuthentication(BaseAuthentication):
    def authenticate(self, request):
        if request.method == 'GET':
            # 读取用户请求token，校验是否合法
            token = str(request.headers.get("Authorization"))
            role = request.headers.get("Roles")

            # 判断前端提供认证是否为空
            if not token:
                raise exceptions.AuthenticationFailed("token为空认证失败")

            if not role:
                raise exceptions.AuthenticationFailed("权限为空认证失败")

            # 判断token和权限是否与数据库一致
            try:
                # 通过数据库或者token或权限
                token_obj = Token.objects.get(token_key=token)
                username = token_obj.User.username
                token_list = str(token_obj)
                role_list = str(Roles.objects.get(role=role))

                if role == role_list and token == token_list:
                    return (User(username, role), None)
                else:
                    raise exceptions.AuthenticationFailed("权限和角色不一致")

            except Exception as e:
                raise exceptions.AuthenticationFailed("权限和角色不存在 %s" % e)

    def authenticate_header(self, request):
        return "API"

# 认证权限角色组件
class MinePermission(BasePagination):
    def has_object_permission(self, request, view, obj):
        # 视图中 self.get_object()
        return True

    def has_permission(self, request, view):
        role_obj = request.headers.get("Roles")

        # 白名单放行登陆
        url = request.get_full_path()
        if url == "/login/":
            return True

        if role_obj == None:
            return False

        # 1、当前用户正在访问的url和方式
        # print(request.resolver_match.url_name, request.method)    # 输出结果就是depart-list GET
        url_name = request.resolver_match.url_name
        method = request.method

        # 2、多对多正向查询权限，获取权限字段, 并重新组合权限字典
        roles_obj = Roles.objects.get(role=role_obj)
        permission_dict = {role_obj: {}}
        for i in roles_obj.permissions.all():
            permission_dict[role_obj][i.url_path] = []

        for k in roles_obj.permissions.all():
            permission_dict[role_obj][k.url_path].append(k.request)

        # 3、 权限判断
        # 获取前端上传角色
        permission_dict = permission_dict[role_obj]

        # 获取request
        method_list = permission_dict.get(url_name)

        # 判断查询request是否有值，无就返回false
        if not method_list:
            return False

        if method in method_list:
            return True

        return False